package cn.bugstack.domain.trade.adapter.repository;

import cn.bugstack.domain.activity.model.entity.UserGroupBuyOrderDetailEntity;
import cn.bugstack.domain.trade.model.aggregate.GroupBuyOrderAggregate;
import cn.bugstack.domain.trade.model.aggregate.GroupBuyRefundAggregate;
import cn.bugstack.domain.trade.model.aggregate.GroupBuyTeamSettlementAggregate;
import cn.bugstack.domain.trade.model.entity.GroupBuyActivityEntity;
import cn.bugstack.domain.trade.model.entity.GroupBuyTeamEntity;
import cn.bugstack.domain.trade.model.entity.MarketPayOrderEntity;
import cn.bugstack.domain.trade.model.entity.NotifyTaskEntity;
import cn.bugstack.domain.trade.model.valobj.GroupBuyProgressVO;

import java.util.List;

/**
 * @description 交易仓储服务接口
 */
public interface ITradeRepository {

    // 查询未支付营销订单，并返回一个 预购订单营销实体对象
    MarketPayOrderEntity queryMarketPayOrderEntityByOutTradeNo(String userId, String outTradeNo);

    // 锁单
    MarketPayOrderEntity lockMarketPayOrder(GroupBuyOrderAggregate groupBuyOrderAggregate);

    // 查询拼团进度
    GroupBuyProgressVO queryGroupBuyProgress(String teamId);

    // 查询拼团活动
    GroupBuyActivityEntity queryGroupBuyActivityEntityByActivityId(Long activityId);

    // 查询用户在一个活动上的参与次数
    Integer queryOrderCountByActivityId(Long activityId, String userId);

    // 查询拼团的组队信息
    GroupBuyTeamEntity queryGroupBuyTeamByTeamId(String teamId);

    // 拼团交易结算，落库
    NotifyTaskEntity settlementMarketPayOrder(GroupBuyTeamSettlementAggregate groupBuyTeamSettlementAggregate);

    // 判断黑名单拦截渠道，true 拦截、false 放行
    boolean isSCBlackIntercept(String source, String channel);

    // 取出 50 条尚未 失败 的回调任务
    List<NotifyTaskEntity> queryUnExecutedNotifyTaskList();

    // 取出单条尚未 失败 的回调任务
    List<NotifyTaskEntity> queryUnExecutedNotifyTaskList(String teamId);

    // 设置队伍的回调任务状态为成功
    int updateNotifyTaskStatusSuccess(NotifyTaskEntity notifyTaskEntity);

    // 设置队伍的回调任务状态为错误
    int updateNotifyTaskStatusError(NotifyTaskEntity notifyTaskEntity);

    // 设置队伍的回调任务状态为重试
    int updateNotifyTaskStatusRetry(NotifyTaskEntity notifyTaskEntity);

    // 锁单前占用库存，占用成功就加锁，每个库存是一个单独的锁，存在即被占用
    boolean occupyTeamStock(String teamStockKey, String recoveryTeamStockKey, Integer target, Integer validTime);

    // 记录占用库存时失败 的 库存消耗量
    void recoveryTeamStock(String recoveryTeamStockKey, Integer validTime);

    // 1、未支付，未成团：事务更新订单状态为退单 和 队伍锁单量-1
    NotifyTaskEntity unpaid2Refund(GroupBuyRefundAggregate groupBuyRefundAggregate);

    // ２、已支付，未成团：事务更新订单状态为退单 和 队伍锁单量-1，完成量-1
    NotifyTaskEntity paid2Refund(GroupBuyRefundAggregate groupBuyRefundAggregate);

    // 3、已支付，已成团：事务更新订单状态为退单 和 队伍锁单量-1，完成量-1，并更新 队伍状态 完成(含退单) / 失败(最后一个订单退单，拼团失败)
    NotifyTaskEntity paidTeam2Refund(GroupBuyRefundAggregate groupBuyRefundAggregate);

    // 恢复退单空出来的库存，库存key，订单Id
    void refund2AddRecovery(String recoveryTeamStockKey, String orderId);

    // 查询超时未支付订单，给予定时器执行退单操作
    List<UserGroupBuyOrderDetailEntity> queryTimeoutUnpaidOrderList();
}
